package br.unifor.ads.desphouse.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import br.unifor.ads.desphouse.entity.Usuario;
import br.unifor.ads.desphouse.to.UsuarioTO;

/**
 * 
 * @author Arley
 */
public class UsuarioDAO {
	private EntityManager em = new EntityManager(){ 
		@Override
		public Object trataResultSet(ResultSet resultSet) throws SQLException {
			Usuario usuario = new Usuario();
			usuario.setCodigo(resultSet.getLong("codigo"));
			usuario.setNome(resultSet.getString("nome"));
			usuario.setChave(resultSet.getString("chave"));
			usuario.setSenha(resultSet.getString("senha"));
			usuario.setAtivo(resultSet.getBoolean("ativo"));
			return usuario;
		}
	};
	
	/**
	 * Inseri um novo Usuario
	 * 
	 * @param usuario
	 * @throws SQLException
	 */
	public Usuario salvar(Usuario usuario) throws SQLException {
		String sql = "insert into seguranca.usuario"
				+ "(nome, chave, senha, ativo) "
				+ "values "
				+ "(?, ?, ?, ?) "
				+ "returning codigo, nome, chave, senha, ativo";
		return (Usuario)em.getSingleResult(sql, usuario.getNome(), usuario.getChave(), usuario.getSenha(), usuario.getAtivo());
	}

	/**
	 * Atualiza os dados de um Usuario
	 * 
	 * @param usuario
	 * @throws SQLException
	 */
	public void atualizar(Usuario usuario) throws SQLException {
		String sql = "update seguranca.usuario set nome = ?, chave = ?, senha = ?, ativo = ? where codigo = ?";
		em.executeQuery(sql, usuario.getNome(), usuario.getChave(), usuario.getSenha(), usuario.getAtivo(), usuario.getCodigo());
	}

	/**
	 * Remove um Usuario a partir do seu codigo
	 * 
	 * @param codigo
	 * @throws SQLException
	 */
	public void excluirPorCodigo(Long codigo) throws SQLException {
		String sql = "delete from seguranca.usuario where codigo = ?";
		em.executeQuery(sql, codigo);
	}
	
	//TODO criar teste
	/**
	 * Remove um usuario a partir da sua chave
	 * @param chave
	 * @throws SQLException
	 */
	public void excluirPorChave(String chave) throws SQLException{
		String sql = "delete from seguranca.usuario where chave = ?";
		em.executeQuery(sql, chave);
	}

	/**
	 * Remove todos os registros da tabela Usuario
	 * 
	 * @throws SQLException
	 */
	public void excluirTodos() throws SQLException {
		String sql = "delete from seguranca.usuario";
		em.executeQuery(sql);
	}

	/**
	 * Retorna um Usuario apartir do seu codigo
	 * 
	 * @param codigo
	 * @return
	 * @throws SQLException
	 */
	public Usuario buscarPorCodigo(Long codigo) throws SQLException {
		String sql = "select codigo, nome, chave, senha, ativo from seguranca.usuario where codigo = ?";
		return (Usuario) em.getSingleResult(sql, codigo);
	}

	/**
	 * Retorna todos os registros de Usuario
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public List<Usuario> buscarTodos() throws SQLException {
		String sql = "select codigo, nome, chave, senha, ativo from seguranca.usuario";
		return (List<Usuario>) em.getResultList(sql);
	}
	
	/**
	 * Retorna um Usuario, apartir da
	 * sua chave de acesso
	 * 
	 * @param chave
	 * @return
	 * @throws SQLException
	 */
	public Usuario buscarPorChave(String chave) throws SQLException {
		String sql = "select codigo, nome, chave, senha, ativo from seguranca.usuario where chave = ?";
		return (Usuario) em.getSingleResult(sql, chave);
	}


	/**
	 * Retorana um Usuario a apartir dos seus
	 * dados de acesso
	 * 
	 * @param chave
	 * @param senha
	 * @return
	 * @throws SQLException
	 */
	public Usuario buscarPorChaveSenha(String chave, String senha) throws SQLException {
		String sql = "select codigo, nome, chave, senha, ativo from seguranca.usuario where chave = ? and senha = ?";
		return (Usuario) em.getSingleResult(sql, chave, senha);
	}

	//TODO criar teste
	@SuppressWarnings("unchecked")
	public List<Usuario> buscarPorFiltro(UsuarioTO to) throws SQLException {
		String sql = "select codigo, nome, chave, senha, ativo from seguranca.usuario where 1=1 ";
		if(to.getChave()!=null && to.getChave().trim().length()>0 &&
				to.getNome()!=null && to.getNome().trim().length()>0){
			sql += "AND chave = ? ";
			sql += "AND nome iLike ? ";
			return (List<Usuario>) em.getResultList(sql,to.getChave(),"%"+to.getNome()+"%");
		}else if(to.getChave()!=null && to.getChave().trim().length()>0){
			sql += "AND chave = ? ";
			return (List<Usuario>) em.getResultList(sql,to.getChave());
		}else if(to.getNome()!=null && to.getNome().trim().length()>0){
			sql += "AND nome iLIKE ? ";
			return (List<Usuario>) em.getResultList(sql,"%"+to.getNome()+"%");
		}
		return (List<Usuario>) em.getResultList(sql);
	}

}
